package dxn.nl.file.center.netty.client;

import dxn.nl.file.center.CsCenterNettyConstants;
import dxn.nl.file.center.SocketManager;
import dxn.nl.file.center.netty.consumer.ConsumerSocketManager;
import dxn.nl.file.client.model.dto.TransferMessageDto;
import dxn.nl.file.client.model.enums.ExportDealResultTypeEnum;
import dxn.nl.file.client.model.enums.ExportMessageTypeEnum;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.SocketChannel;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ExportNettyServerHandler extends SimpleChannelInboundHandler<TransferMessageDto> {
    private static final Logger log = LoggerFactory.getLogger(ExportNettyServerHandler.class);

    @Override
    protected void channelRead0(ChannelHandlerContext context, TransferMessageDto dto) {
        SocketChannel socketChannel = (SocketChannel) context.channel();
        //String message = (String)obj;

        try{
            int type = dto.getType();

            // 非注册消息，如果没有appid或者sessionId,则连接无效，断开连接
            if (type != ExportMessageTypeEnum.server_connect.code
                    && type != ExportMessageTypeEnum.client_connect.code)
            {
                String appId = socketChannel.attr(CsCenterNettyConstants.APP_ID).get();
                String sessionId = socketChannel.attr(CsCenterNettyConstants.APP_SESSION_ID).get();
                if(StringUtils.isBlank(appId) || StringUtils.isBlank(sessionId))
                {
                    log.info("appId:{} sessionId: {} 为空",appId,sessionId);
                    socketChannel.close();
                    return;
                }

                if(!ClientSocketManager.contains(appId,sessionId))
                {
                    log.info("appId:{} sessionId: {} ,未能成功注册",appId,sessionId);
                    socketChannel.close();
                    return;
                }
            }

            String appId = socketChannel.attr(CsCenterNettyConstants.APP_ID).get();
            String sessionId = socketChannel.attr(CsCenterNettyConstants.APP_SESSION_ID).get();

            if(type == ExportMessageTypeEnum.heartbeat.code)
            {
                ClientSocketManager.refreshClient(appId,sessionId);
                // 心跳包,刷新时间,直接回写
                SocketManager.sendNoResult(socketChannel, dto);
                return ;
            }
            dealData(socketChannel,dto);
        }
        catch (Exception ex)
        {
            log.error("",ex);
        }
        finally {
            //ReferenceCountUtil.release(byteBuf);
        }
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        log.info(">>>>>>>>连接");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        SocketChannel socketChannel = (SocketChannel) ctx.channel();
        String appId = socketChannel.attr(CsCenterNettyConstants.APP_ID).get();
        String sessionId = socketChannel.attr(CsCenterNettyConstants.APP_SESSION_ID).get();
        if(appId == null || sessionId==null)
        {
            return ;
        }
        String ipPort = socketChannel.remoteAddress().getHostString()+":"+socketChannel.remoteAddress().getPort();
        ClientSocketManager.removeClient(appId,sessionId);
        log.info(socketChannel.localAddress()+">>>>>>>>退出");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("",cause);
        ctx.close();
    }

    private void dealData(SocketChannel socketChannel, TransferMessageDto message) {
        //log.info(">>>>>>>>>>>服务端接收到客户端的消息：{}",obj);
        int type = message.getType();

        // 如果是连接，记录socket
        if (type == ExportMessageTypeEnum.client_connect.code) {
            ClientSocketManager.addClient(message.getConfig().getAppId(), message.getConfig().getSessionId(), socketChannel);
            return;
        }

        // 获取当前通道的sessionId 和 appId
        String appSessionId = socketChannel.attr(CsCenterNettyConstants.APP_SESSION_ID).get();
        message.getConfig().setDealSession(appSessionId);
        // 客户端发出 申请和发送数据
        if (ExportMessageTypeEnum.create_export.code != type
                && ExportMessageTypeEnum.send_data.code != type) {
            // 如果是处理结果的话，直接给future赋值，结束
            if (StringUtils.isBlank(message.getConfig().getServer())) {
                // from来源客户端没有了，就没有办法，发送给原来的客户端了
                SocketManager.sendErrorNoResult(socketChannel, message, "server不能为空");
                return;
            }
        }

        SocketChannel serverChannel = ConsumerSocketManager.getChannel(message.getConfig().getServer());

        if (serverChannel != null) {
            SocketManager.sendNoResult(serverChannel, message);
        } else {
            SocketManager.sendErrorNoResult(socketChannel, message, ExportDealResultTypeEnum.nextIp.code,"未找到对应form客户端");
        }
    }
}